using System.Linq.Expressions;

namespace WeatherSystem.API.Specifications
{
    /// <summary>
    /// Specification pattern base interface
    ///
    /// 实现规约模式，提供灵活的查询构建能力，
    /// 支持复杂查询条件的组合和重用
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    public interface ISpecification<T>
    {
        /// <summary>
        /// 查询条件（WHERE子句）
        /// </summary>
        Expression<Func<T, bool>>? Criteria { get; }

        /// <summary>
        /// 包含的导航属性（用于JOIN操作）
        /// </summary>
        List<Expression<Func<T, object>>> Includes { get; }

        /// <summary>
        /// 字符串形式的包含属性（支持多层导航）
        /// </summary>
        List<string> IncludeStrings { get; }

        /// <summary>
        /// 升序排序字段
        /// </summary>
        Expression<Func<T, object>>? OrderBy { get; }

        /// <summary>
        /// 降序排序字段
        /// </summary>
        Expression<Func<T, object>>? OrderByDescending { get; }

        /// <summary>
        /// 分组字段
        /// </summary>
        Expression<Func<T, object>>? GroupBy { get; }

        /// <summary>
        /// 分页获取数量（LIMIT）
        /// </summary>
        int Take { get; }

        /// <summary>
        /// 分页跳过数量（OFFSET）
        /// </summary>
        int Skip { get; }

        /// <summary>
        /// 是否启用分页
        /// </summary>
        bool IsPagingEnabled { get; }
    }

    /// <summary>
    /// Base specification implementation
    ///
    /// 规约模式的基类实现，提供查询构建的核心功能
    /// 支持链式调用和方法链构建复杂查询
    /// </summary>
    /// <typeparam name="T">实体类型</typeparam>
    public abstract class BaseSpecification<T> : ISpecification<T>
    {
        /// <summary>
        /// 无参构造函数，用于动态构建查询条件
        /// </summary>
        protected BaseSpecification() { }

        /// <summary>
        /// 带查询条件的构造函数
        /// </summary>
        /// <param name="criteria">查询条件表达式</param>
        protected BaseSpecification(Expression<Func<T, bool>> criteria)
        {
            Criteria = criteria;
        }

        /// <summary>
        /// 查询条件（WHERE子句）
        /// </summary>
        public Expression<Func<T, bool>>? Criteria { get; }

        /// <summary>
        /// 包含的导航属性列表
        /// </summary>
        public List<Expression<Func<T, object>>> Includes { get; } = new();

        /// <summary>
        /// 字符串形式的包含属性列表
        /// </summary>
        public List<string> IncludeStrings { get; } = new();

        /// <summary>
        /// 升序排序字段
        /// </summary>
        public Expression<Func<T, object>>? OrderBy { get; private set; }

        /// <summary>
        /// 降序排序字段
        /// </summary>
        public Expression<Func<T, object>>? OrderByDescending { get; private set; }

        /// <summary>
        /// 分组字段
        /// </summary>
        public Expression<Func<T, object>>? GroupBy { get; private set; }

        /// <summary>
        /// 分页获取数量
        /// </summary>
        public int Take { get; private set; }

        /// <summary>
        /// 分页跳过数量
        /// </summary>
        public int Skip { get; private set; }

        /// <summary>
        /// 是否启用分页
        /// </summary>
        public bool IsPagingEnabled { get; private set; }

        /// <summary>
        /// 添加导航属性包含
        /// </summary>
        /// <param name="includeExpression">导航属性表达式</param>
        protected virtual void AddInclude(Expression<Func<T, object>> includeExpression)
        {
            Includes.Add(includeExpression);
        }

        /// <summary>
        /// 添加字符串形式的包含属性
        /// </summary>
        /// <param name="includeString">包含属性字符串（如"Metrics.Definition"）</param>
        protected virtual void AddInclude(string includeString)
        {
            IncludeStrings.Add(includeString);
        }

        /// <summary>
        /// 应用分页设置
        /// </summary>
        /// <param name="skip">跳过数量</param>
        /// <param name="take">获取数量</param>
        public virtual void ApplyPaging(int skip, int take)
        {
            Skip = skip;
            Take = take;
            IsPagingEnabled = true;
        }

        /// <summary>
        /// 应用升序排序
        /// </summary>
        /// <param name="orderByExpression">排序表达式</param>
        public virtual void ApplyOrderBy(Expression<Func<T, object>> orderByExpression)
        {
            OrderBy = orderByExpression;
        }

        /// <summary>
        /// 应用降序排序
        /// </summary>
        /// <param name="orderByDescExpression">降序排序表达式</param>
        public virtual void ApplyOrderByDescending(Expression<Func<T, object>> orderByDescExpression)
        {
            OrderByDescending = orderByDescExpression;
        }

        /// <summary>
        /// 应用分组
        /// </summary>
        /// <param name="groupByExpression">分组表达式</param>
        protected virtual void ApplyGroupBy(Expression<Func<T, object>> groupByExpression)
        {
            GroupBy = groupByExpression;
        }
    }
}